﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using IFDB.Models.Contexts;
using IFDB.ResourceLibrary;
using IFDB.Models.Foundation;

namespace IFDB.Models.Tables
{
    public partial class Match : BaseTable<Match>
    {
        public Match()
        {
            this.AppearanceEvents = new HashSet<AppearanceEvent>();
            this.LookupMatches = new HashSet<LookupMatch>();
        }

        public Guid MatchId { get; set; }
        public MatchStatus MatchStatus { get; set; }
        public DateTime MatchDate { get; set; }
        public Guid CompetitionId { get; set; }
        public Nullable<Guid> VenueId { get; set; }
        public long? Attendance { get; set; }

        [ForeignKey("Team1")]
        public Guid Team1Id { get; set; }
        public short? Team1HT { get; set; }
        public short? Team1FT { get; set; }
        public short? Team1ETHT { get; set; }
        public short? Team1ETFT { get; set; }
        public short? Team1ETPens { get; set; }

        [ForeignKey("Team2")]
        public Guid Team2Id { get; set; }
        public short? Team2HT { get; set; }
        public short? Team2FT { get; set; }
        public short? Team2ETHT { get; set; }
        public short? Team2ETFT { get; set; }
        public short? Team2ETPens { get; set; }

        public virtual ICollection<AppearanceEvent> AppearanceEvents { get; set; }
        public virtual Competition Competition { get; set; }
        public virtual ICollection<LookupMatch> LookupMatches { get; set; }

        [InverseProperty("Team1Matches")]
        public virtual Team Team1 { get; set; }

        [InverseProperty("Team2Matches")]
        public virtual Team Team2 { get; set; }
        public virtual Venue Venue { get; set; }

        public static Match CreateNew(MatchStatus matchStatus, DateTime matchDate, Guid competitionId, Guid? venueId, long? attendance, Guid team1Id, short? team1HT, short? team1FT, short? team1ETHT, short? team1ETFT, short? team1ETPens, Guid team2Id, short? team2HT, short? team2FT, short? team2ETHT, short? team2ETFT, short? team2ETPens)
        {
            return new Match()
            {
                MatchId = Guid.NewGuid(),
                MatchStatus = matchStatus,
                MatchDate = matchDate,
                CompetitionId = competitionId,
                VenueId = venueId,
                Attendance = attendance,
                Team1Id = team1Id,
                Team1HT = team1HT,
                Team1FT = team1FT,
                Team1ETHT = team1ETHT,
                Team1ETFT = team1ETFT,
                Team1ETPens = team1ETPens,
                Team2Id = team2Id,
                Team2HT = team2HT,
                Team2FT = team2FT,
                Team2ETHT = team2ETHT,
                Team2ETFT = team2ETFT,
                Team2ETPens = team2ETPens
            };
        }

        public static Match Update(Match match, MatchStatus matchStatus, DateTime matchDate, Guid competitionId, Guid? venueId, long? attendance, Guid team1Id, short? team1HT, short? team1FT, short? team1ETHT, short? team1ETFT, short? team1ETPens, Guid team2Id, short? team2HT, short? team2FT, short? team2ETHT, short? team2ETFT, short? team2ETPens)
        {
            match.MatchStatus = matchStatus;
            match.MatchDate = matchDate;
            match.CompetitionId = competitionId;
            match.VenueId = venueId;
            match.Attendance = attendance;
            match.Team1Id = team1Id;
            match.Team1HT = team1HT;
            match.Team1FT = team1FT;
            match.Team1ETHT = team1ETHT;
            match.Team1ETFT = team1ETFT;
            match.Team1ETPens = team1ETPens;
            match.Team2Id = team2Id;
            match.Team2HT = team2HT;
            match.Team2FT = team2FT;
            match.Team2ETHT = team2ETHT;
            match.Team2ETFT = team2ETFT;
            match.Team2ETPens = team2ETPens;

            return match;
        }

        public static Match Search(IFDBContext db, DateTime matchDate, Guid competitionId, Guid team1Id, Guid team2Id)
        {
            DateTime startOfDay = matchDate.StartOfDay();
            DateTime endOfDay = matchDate.EndOfDay();

            var localQuery = from match in db.Matches.Local
                             where match.Team1Id == team1Id
                             && match.Team2Id == team2Id
                             && match.CompetitionId == competitionId
                             && match.MatchDate >= startOfDay
                             && match.MatchDate <= endOfDay
                             select match;

            var query = from match in db.Matches
                        where match.Team1Id == team1Id
                        && match.Team2Id == team2Id
                        && match.CompetitionId == competitionId
                        && match.MatchDate >= startOfDay
                        && match.MatchDate <= endOfDay
                        select match;

            var search = ProcessSearch(localQuery, query, false);
            return search != null ? search.Single() : null;
        }
    }
}
